package com.java110.attendance.changpai;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.core.adapt.ICallAccessControlService;
import com.java110.core.adapt.attendance.IAttendanceMachineProcess;
import com.java110.core.adapt.attendance.ICallAttendanceService;
import com.java110.core.constant.ResponseConstant;
import com.java110.core.factory.CallAttendanceFactory;
import com.java110.core.factory.MappingCacheFactory;
import com.java110.core.factory.MqttFactory;
import com.java110.core.factory.NotifyAccessControlFactory;
import com.java110.core.service.community.ICommunityService;
import com.java110.core.service.machine.IMachineService;
import com.java110.core.util.DateUtil;
import com.java110.core.util.StringUtil;
import com.java110.entity.attendance.ClockInDto;
import com.java110.entity.attendance.ClockInResultDto;
import com.java110.entity.cloud.MachineCmdResultDto;
import com.java110.entity.cloud.MachineHeartbeatDto;
import com.java110.entity.machine.MachineDto;
import com.java110.entity.machine.OperateLogDto;
import com.java110.entity.response.ResultDto;
import com.java110.entity.user.StaffDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 厂拍科技
 * 文档地址
 * https://www.yuque.com/fengjing-pu9cj/keyp1f/eta2tc?singleDoc#tuoXc
 * https://www.yuque.com/fengjing-pu9cj/keyp1f/symmrgp320mcrl5n?singleDoc#QEu5J
 */
@Service("cpAttendanceMachineProcessAdapt")
public class CpAttendanceMachineProcessAdapt implements IAttendanceMachineProcess {

    private static Logger logger = LoggerFactory.getLogger(CpAttendanceMachineProcessAdapt.class);

    public static final String FACE_URL = "ACCESS_CONTROL_FACE_URL";

    @Autowired
    private IMachineService machineServiceImpl;

    @Autowired
    private ICommunityService communityServiceImpl;

    //发布
    private static final String REQUEST_FACE = "changpai/topic/face/manage/request/SN";
    //接受
    private static final String RESPONSE_FACE = "changpai/topic/face/manage/response/";


    private static final String UPLOAD_RESPONSE_FACE = "changpai/topic/face/capture/request/";


    //心跳
    private static final String HEARTBEAT_FACE = "changpai/topic/face/heart/request/";

    private static final String SN = "SN";

    //图片后缀
    public static final String IMAGE_SUFFIX = ".jpg";

    @Override
    public void initMachine(MachineDto machineDto) {
        MqttFactory.subscribe("changpai/topic/face/capture/request/" + machineDto.getMachineCode().trim());
        MqttFactory.subscribe("changpai/topic/face/manage/response/" + machineDto.getMachineCode().trim());
        MqttFactory.subscribe("changpai/topic/face/heart/request/" + machineDto.getMachineCode().trim());
    }

    @Override
    public void restartAttendanceMachine(MachineDto machineDto, StaffDto staffDto) {

        JSONObject param = JSONObject.parseObject("{\n" +
                "  \"cmd\": \"reboot\"\n" +
                "}");
        MqttFactory.publish(REQUEST_FACE.replace(SN, machineDto.getMachineCode()), param.toJSONString());

    }

    @Override
    public ResultDto addFace(MachineDto machineDto, StaffDto staffDto) {

        JSONObject param = new JSONObject();
        param.put("cmd", "upload person");
        param.put("id", staffDto.getStaffId());
        param.put("name", staffDto.getStaffName());
        param.put("role", 1);
        param.put("kind", 0);
        param.put("reg_image", staffDto.getFaceBase64());
        MqttFactory.publish(REQUEST_FACE.replace(SN, machineDto.getMachineCode()), param.toJSONString());
        saveLog(staffDto.getTaskId(), machineDto.getMachineId(), REQUEST_FACE.replace(SN, machineDto.getMachineCode()) + "/uploadperson", param.toJSONString(), "", "", staffDto.getStaffId(), staffDto.getStaffName());
        return new ResultDto(ResultDto.SUCCESS, "成功");
    }

    @Override
    public ResultDto updateFace(MachineDto machineDto, StaffDto staffDto) {
        deleteFace(machineDto, staffDto);
        addFace(machineDto, staffDto);
        return new ResultDto(ResultDto.SUCCESS, "成功");
    }

    @Override
    public ResultDto deleteFace(MachineDto machineDto, StaffDto staffDto) {
        JSONObject param = new JSONObject();
        param.put("cmd", "delete person");
        param.put("flag", -1);
        param.put("id", staffDto.getStaffId());
        MqttFactory.publish(REQUEST_FACE.replace(SN, machineDto.getMachineCode()), param.toJSONString());
        saveLog(staffDto.getTaskId(), machineDto.getMachineId(), REQUEST_FACE.replace(SN, machineDto.getMachineCode()) + "/deleteperson", param.toJSONString(), "", "", staffDto.getStaffId(), staffDto.getStaffName());
        return new ResultDto(ResultDto.SUCCESS, "成功");
    }

    @Override
    public void mqttMessageArrived(String taskId, String topic, String data) {

        JSONObject param = JSONObject.parseObject(data);

        String cmd = param.getString("cmd");

        if ("face".equals(cmd)) {
            clockIn(param);

        }
        if (topic.startsWith(HEARTBEAT_FACE)) {
            heartbeat(param);
        }

        if (topic.startsWith(RESPONSE_FACE)) {
            doCmdResultCloud(param);
        }

    }

    public void heartbeat(JSONObject info) {
        try {
            String machineCode = info.getString("device_sn");
            String heartBeatTime = null;
            heartBeatTime = DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A);
            MachineHeartbeatDto machineHeartbeatDto = new MachineHeartbeatDto(machineCode, heartBeatTime);
            ICallAccessControlService notifyAccessControlService = NotifyAccessControlFactory.getCallAccessControlService();
            notifyAccessControlService.machineHeartbeat(machineHeartbeatDto);
            JSONObject resultParam = new JSONObject();
            resultParam.put("result", 1);
            resultParam.put("success", true);

            JSONObject result = new JSONObject();
            result.put("reply", "ACK");
            result.put("cmd", "heart beat");
            result.put("code", 0);
            result.put("device_sn", machineCode);
            MqttFactory.publish(RESPONSE_FACE + machineCode, result.toJSONString());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ResultDto clearFace(MachineDto machineDto, StaffDto staffDto) {
        return null;
    }

    @Override
    public String getDefaultResult() {
        return null;
    }

    /**
     * 存储日志
     *
     * @param logId     日志ID
     * @param machineId 设备ID
     * @param cmd       操作命令
     * @param reqParam  请求报文
     * @param resParam  返回报文
     * @param state     状态
     * @param userId    业主ID
     * @param userName  业主名称
     */
    protected void saveLog(String logId, String machineId, String cmd, String reqParam, String resParam, String state, String userId, String userName) {
        ICallAccessControlService notifyAccessControlService = NotifyAccessControlFactory.getCallAccessControlService();
        OperateLogDto operateLogDto = new OperateLogDto();
        operateLogDto.setLogId(logId);
        operateLogDto.setMachineId(machineId);
        operateLogDto.setOperateType(cmd);
        operateLogDto.setReqParam(reqParam);
        operateLogDto.setResParam(resParam);
        operateLogDto.setState(state);
        operateLogDto.setUserId(userId);
        operateLogDto.setUserName(userName);
        notifyAccessControlService.saveOrUpdateOperateLog(operateLogDto);
    }


    private void doCmdResultCloud(JSONObject resultCmd) {
        try {
            String taskId = resultCmd.getString("id");
            int code = -1;
            if (!resultCmd.containsKey("status")) {
                code = -1;
            } else {
                String status = resultCmd.getString("status");
                if ("ok".equals(status)) {
                    code = 0;
                } else {
                    code = -1;
                }
            }
            String msg = resultCmd.getString("message_info");
            ICallAccessControlService notifyAccessControlService = NotifyAccessControlFactory.getCallAccessControlService();
            MachineCmdResultDto machineCmdResultDto = new MachineCmdResultDto(code, msg, taskId, "", resultCmd.toJSONString());
            notifyAccessControlService.machineCmdResult(machineCmdResultDto);
        } catch (Exception e) {
            logger.error("上报执行命令失败", e);
        }
    }

    /**
     * 打卡记录
     *
     * @param paramJson
     */
    private void clockIn(JSONObject paramJson) {
        logger.debug("考勤结果,{}", paramJson.toJSONString());
        if(!paramJson.containsKey("match")){
            return ;
        }
        JSONObject dataObj = paramJson.getJSONObject("match");

        if (!dataObj.containsKey("person_id") || StringUtil.isEmpty(dataObj.getString("person_id"))) {
            return;
        }
        try {

            String staffId = dataObj.getString("person_id");
            ICallAttendanceService callAttendanceService = CallAttendanceFactory.getCallAttendanceService();
            ClockInDto clockInDto = new ClockInDto();
            clockInDto.setStaffId(staffId);
            Date date = new Date();
            //date.setTime(dataObj.getLong("recog_time"));
            clockInDto.setClockInTime(DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A));
            clockInDto.setClockInTime(DateUtil.getFormatTimeString(date, DateUtil.DATE_FORMATE_STRING_A));
            clockInDto.setPic(dataObj.getString("image"));
            ClockInResultDto resultDto = callAttendanceService.clockIn(clockInDto);
            logger.debug("考勤结果,{}", JSONObject.toJSONString(resultDto));

            JSONObject result = new JSONObject();
            result.put("reply", "ACK");
            result.put("cmd", "face");
            result.put("code", 0);
            result.put("sequence_no", paramJson.getString("sequence_no"));
            result.put("cap_time", paramJson.getString("cap_time"));
            JSONObject tts = new JSONObject();
            tts.put("text",  resultDto.getMsg());
            result.put("tts", tts);
            MqttFactory.publish(RESPONSE_FACE + paramJson.getString("device_sn"), result.toJSONString());

            String viewText = "{\n" +
                    " \"cmd\": \"text display\",\n" +
                    " \"coding_type\":\"utf8\",\n" +
                    " \"text_list\":[\n" +
                    "  {\n" +
                    "   \"position\":{\n" +
                    "    \"x\":40,\n" +
                    "    \"y\":800\n" +
                    "   },\n" +
                    "   \"alive_time\": 3000,\n" +
                    "   \"font_size\": 50,\n" +
                    "   \"font_spacing\": 1,\n" +
                    "   \"font_color\": \"0xff00ff00\",\n" +
                    "   \"text\":\"" + dataObj.getString("person_name") + "\"\n" +
                    "  },\n" +
                    "  {\n" +
                    "   \"position\":{\n" +
                    "    \"x\":10,\n" +
                    "    \"y\":850\n" +
                    "   },\n" +
                    "   \"alive_time\": 3000,\n" +
                    "   \"font_size\": 50,\n" +
                    "   \"font_spacing\": 1,\n" +
                    "   \"font_color\": \"0xff00ff00\",\n" +
                    "   \"text\":\"" + resultDto.getMsg() + "\"\n" +
                    "  }\n" +
                    " ]\n" +
                    "}";
            MqttFactory.publish(REQUEST_FACE.replace(SN, paramJson.getString("device_sn")), viewText);

        } catch (Exception e) {
            logger.error("考勤失败", e);
        }
    }

    public static void main(String[] args) {
        Date time = new Date();
        System.out.println(time.getTime());
        Date date = new Date();
        date.setTime(1659577546);
        System.out.println(date);
    }
}
